package com.ym.utils;

import com.alibaba.fastjson.JSON;
import com.google.gson.*;
import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

public class JsonUtil {

    public static GsonBuilder gb = new GsonBuilder().registerTypeAdapter(Date.class, new DateAdapter()).registerTypeAdapter(Timestamp.class,new TimestampAdapter());
    public static Gson gson = gb.serializeNulls().create();

    /**
     * json字符串转换成泛型对象
     * @param json
     * @param objClass  最后得到的对象
     * @param clazz     泛型对象
     * @param <T>
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static  <T> T fromJson(String json, Class objClass,Class clazz) {
        Type objectType = type(objClass, clazz);
        return gson.fromJson(json, objectType);
    }

    /**
     * 泛型对象组装
     * @param raw
     * @param args
     * @return
     */
    @SuppressWarnings("rawtypes")
    static ParameterizedType type(final Class raw, final Type... args) {
        return new ParameterizedType() {
            public Type getRawType() {
                return raw;
            }
            public Type[] getActualTypeArguments() {
                return args;
            }
            public Type getOwnerType() {
                return null;
            }
        };
    }

    /**
     * 将对象转化为json串
     * @param object 对象
     * @return json串
     */
    public static String toJson(Object object){
        return gson.toJson(object);
    }

    /**
     * 对象 转 Map
     */
    public static Map<String,Object> beanToMap(Object object){
        return JSON.parseObject(toJson(object)).getInnerMap();
    }

    /**
     * 对象集合 转 List<Map>
     */
    public static List<Map<String,Object>> beanToList(List<?> list){
        return list.stream().map(x->JSON.parseObject(toJson(x)).getInnerMap()).collect(Collectors.toList());
    }

    /**
     * JSON 转 对象
     */
    public static <T> T jsonToBean(String str, Class<T> type) {
        return gson.fromJson(str, type);
    }

    /**
     * Map 转 对象
     */
    public static <T> T mapToBean(Map map, Class<T> clazz) {
        return jsonToBean(toJson(map),clazz);
    }

    static class TimestampAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp> {
        @Override
        public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if(json == null){
                return null;
            } else {
                try {
                    return new Timestamp(json.getAsLong());
                } catch (Exception e) {
                    return null;
                }
            }
        }

        @Override
        public JsonElement serialize(Timestamp src, Type typeOfSrc, JsonSerializationContext context) {
            String value = "";
            if(src != null){
                value = String.valueOf(src.getTime());
            }
            return new JsonPrimitive(value);
        }
    }

    static class DateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date>{
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if(json == null){
                return null;
            } else {
                try {
                    return new Date(json.getAsLong());
                } catch (Exception e) {
                    return null;
                }
            }
        }

        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            String value = "";
            if(src != null){
                value = String.valueOf(src.getTime());
            }
            return new JsonPrimitive(value);
        }
    }
    /**
     * 请求到的json数据转换为List
     * @param orderList
     * @return
     */
    public static List<Map<String,Object>> result2list(JSONArray orderList){
        List<Map<String,Object>> resultList = new ArrayList<>();
        Map<String,Object> resultMap = null;
        Iterator<Object> ianswers  = orderList.iterator();
        while (ianswers.hasNext()) {
            resultMap = new HashMap<>();
            String str = ianswers.next().toString();
            JSONObject obj =  new JSONObject(str);
            Iterator<String> nameList = obj.keys();
            while (nameList.hasNext()) {
                String key = nameList.next().toString();
                String value = obj.get(key).toString();
                resultMap.put(key, value);
            }
            resultList.add(resultMap);
        }
        return resultList;
    }
}
